home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mgr / sparcmgr / demo2.zoo / demo / ex / ex_cmds.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-04-24  |  13.9 KB  |  889 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6.  
  7. #ifndef lint
  8. static char *sccsid = "@(#)ex_cmds.c    7.11 (Berkeley) 3/9/87; 1.2 (Bellcore)    87/04/24";
  9. #endif not lint
  10.  
  11. #include "ex.h"
  12. #include "ex_argv.h"
  13. #include "ex_temp.h"
  14. #include "ex_tty.h"
  15. #include "ex_vis.h"
  16.  
  17. bool    pflag, nflag;
  18. int    poffset;
  19.  
  20. #define    nochng()    lchng = chng
  21.  
  22. /*
  23.  * Main loop for command mode command decoding.
  24.  * A few commands are executed here, but main function
  25.  * is to strip command addresses, do a little address oriented
  26.  * processing and call command routines to do the real work.
  27.  */
  28. commands(noprompt, exitoneof)
  29.     bool noprompt, exitoneof;
  30. {
  31.     register line *addr;
  32.     register int c;
  33.     register int lchng;
  34.     int given;
  35.     int seensemi;
  36.     int cnt;
  37.     bool hadpr;
  38.  
  39.     resetflav();
  40.     nochng();
  41.     for (;;) {
  42.         /*
  43.          * If dot at last command
  44.          * ended up at zero, advance to one if there is a such.
  45.          */
  46.         if (dot <= zero) {
  47.             dot = zero;
  48.             if (dol > zero)
  49.                 dot = one;
  50.         }
  51.         shudclob = 0;
  52.  
  53.         /*
  54.          * If autoprint or trailing print flags,
  55.          * print the line at the specified offset
  56.          * before the next command.
  57.          */
  58.         if (pflag ||
  59.             lchng != chng && value(AUTOPRINT) && !inglobal && !inopen && endline) {
  60.             pflag = 0;
  61.             nochng();
  62.             if (dol != zero) {
  63.                 addr1 = addr2 = dot + poffset;
  64.                 if (addr1 < one || addr1 > dol)
  65. error("Offset out-of-bounds|Offset after command too large");
  66.                 setdot1();
  67.                 goto print;
  68.             }
  69.         }
  70.         nochng();
  71.  
  72.         /*
  73.          * Print prompt if appropriate.
  74.          * If not in global flush output first to prevent
  75.          * going into pfast mode unreasonably.
  76.          */
  77.         if (inglobal == 0) {
  78.             flush();
  79.             if (!hush && value(PROMPT) && !globp && !noprompt && endline) {
  80.                 ex_putchar(':');
  81.                 hadpr = 1;
  82.             }
  83.             TSYNC();
  84.         }
  85.  
  86.         /*
  87.          * Gobble up the address.
  88.          * Degenerate addresses yield ".".
  89.          */
  90.         addr2 = 0;
  91.         given = seensemi = 0;
  92.         do {
  93.             addr1 = addr2;
  94.             addr = address((char *) 0);
  95.             c = getcd();
  96.             if (addr == 0)
  97.                 if (c == ',')
  98.                     addr = dot;
  99.                 else if (addr1 != 0) {
  100.                     addr2 = dot;
  101.                     break;
  102.                 } else
  103.                     break;
  104.             addr2 = addr;
  105.             given++;
  106.             if (c == ';') {
  107.                 c = ',';
  108.                 dot = addr;
  109.                 seensemi = 1;
  110.             }
  111.         } while (c == ',');
  112.         if (c == '%') {
  113.             /* %: same as 1,$ */
  114.             addr1 = one;
  115.             addr2 = dol;
  116.             given = 2;
  117.             c = ex_getchar();
  118.         }
  119.         if (addr1 == 0)
  120.             addr1 = addr2;
  121.         if (c == ':')
  122.             c = ex_getchar();
  123.  
  124.         /*
  125.          * Set command name for special character commands.
  126.          */
  127.         tailspec(c);
  128.  
  129.         /*
  130.          * If called via : escape from open or visual, limit
  131.          * the set of available commands here to save work below.
  132.          */
  133.         if (inopen) {
  134.             if (c=='\n' || c=='\r' || c==CTRL(d) || c==EOF) {
  135.                 if (addr2)
  136.                     dot = addr2;
  137.                 if (c == EOF)
  138.                     return;
  139.                 continue;
  140.             }
  141.             if (any(c, "o"))
  142. notinvis:
  143.                 tailprim(Command, 1, 1);
  144.         }
  145.         switch (c) {
  146.  
  147.         case 'a':
  148.  
  149.             switch(peekchar()) {
  150.             case 'b':
  151. /* abbreviate */
  152.                 tail("abbreviate");
  153.                 setnoaddr();
  154.                 mapcmd(0, 1);
  155.                 anyabbrs = 1;
  156.                 continue;
  157.             case 'r':
  158. /* args */
  159.                 tail("args");
  160.                 setnoaddr();
  161.                 eol();
  162.                 pargs();
  163.                 continue;
  164.             }
  165.  
  166. /* append */
  167.             if (inopen)
  168.                 goto notinvis;
  169.             tail("append");
  170.             setdot();
  171.             aiflag = exclam();
  172.             newline();
  173.             vmacchng(0);
  174.             deletenone();
  175.             setin(addr2);
  176.             inappend = 1;
  177.             ignore(append(gettty, addr2));
  178.             inappend = 0;
  179.             nochng();
  180.             continue;
  181.  
  182.         case 'c':
  183.             switch (peekchar()) {
  184.  
  185. /* copy */
  186.             case 'o':
  187.                 tail("copy");
  188.                 vmacchng(0);
  189.                 move();
  190.                 continue;
  191.  
  192. #ifdef CHDIR
  193. /* cd */
  194.             case 'd':
  195.                 tail("cd");
  196.                 goto changdir;
  197.  
  198. /* chdir */
  199.             case 'h':
  200.                 ignchar();
  201.                 if (peekchar() == 'd') {
  202.                     register char *p;
  203.                     tail2of("chdir");
  204. changdir:
  205.                     if (savedfile[0] == '/' || !value(WARN))
  206.                         ignore(exclam());
  207.                     else
  208.                         ignore(quickly());
  209.                     if (skipend()) {
  210.                         p = getenv("HOME");
  211.                         if (p == NULL)
  212.                             error("Home directory unknown");
  213.                     } else
  214.                         getone(), p = file;
  215.                     eol();
  216.                     if (chdir(p) < 0)
  217.                         filioerr(p);
  218.                     if (savedfile[0] != '/')
  219.                         edited = 0;
  220.                     continue;
  221.                 }
  222.                 if (inopen)
  223.                     tailprim("change", 2, 1);
  224.                 tail2of("change");
  225.                 break;
  226.  
  227. #endif
  228.             default:
  229.                 if (inopen)
  230.                     goto notinvis;
  231.                 tail("change");
  232.                 break;
  233.             }
  234. /* change */
  235.             aiflag = exclam();
  236.             setCNL();
  237.             vmacchng(0);
  238.             setin(addr1);
  239.             ex_delete(0);
  240.             inappend = 1;
  241.             ignore(append(gettty, addr1 - 1));
  242.             inappend = 0;
  243.             nochng();
  244.             continue;
  245.  
  246. /* delete */
  247.         case 'd':
  248.             /*
  249.              * Caution: dp and dl have special meaning already.
  250.              */
  251.             tail("delete");
  252.             c = cmdreg();
  253.             setCNL();
  254.             vmacchng(0);
  255.             if (c)
  256.                 YANKreg(c);
  257.             ex_delete(0);
  258.             appendnone();
  259.             continue;
  260.  
  261. /* edit */
  262. /* ex */
  263.         case 'e':
  264.             tail(peekchar() == 'x' ? "ex" : "edit");
  265. editcmd:
  266.             if (!exclam() && chng)
  267.                 c = 'E';
  268.             filename(c);
  269.             if (c == 'E') {
  270.                 ungetchar(lastchar());
  271.                 ignore(quickly());
  272.             }
  273.             setnoaddr();
  274. doecmd:
  275.             init();
  276.             addr2 = zero;
  277.             laste++;
  278.             ex_sync();
  279.             rop(c);
  280. #ifdef VMUNIX
  281.             tlaste();
  282. #endif
  283.             laste = 0;
  284.             ex_sync();
  285.             nochng();
  286.             continue;
  287.  
  288. /* file */
  289.         case 'f':
  290.             tail("file");
  291.             setnoaddr();
  292.             filename(c);
  293.             noonl();
  294. /*
  295.             synctmp();
  296. */
  297.             continue;
  298.  
  299. /* global */
  300.         case 'g':
  301.             tail("global");
  302.             global(!exclam());
  303.             nochng();
  304.             continue;
  305.  
  306. /* insert */
  307.         case 'i':
  308.             if (inopen)
  309.                 goto notinvis;
  310.             tail("insert");
  311.             setdot();
  312.             nonzero();
  313.             aiflag = exclam();
  314.             newline();
  315.             vmacchng(0);
  316.             deletenone();
  317.             setin(addr2);
  318.             inappend = 1;
  319.             ignore(append(gettty, addr2 - 1));
  320.             inappend = 0;
  321.             if (dot == zero && dol > zero)
  322.                 dot = one;
  323.             nochng();
  324.             continue;
  325.  
  326. /* join */
  327.         case 'j':
  328.             tail("join");
  329.             c = exclam();
  330.             setcount();
  331.             nonzero();
  332.             newline();
  333.             vmacchng(0);
  334.             if (given < 2 && addr2 != dol)
  335.                 addr2++;
  336.             join(c);
  337.             continue;
  338.  
  339. /* k */
  340.         case 'k':
  341. casek:
  342.             pastwh();
  343.             c = ex_getchar();
  344.             if (endcmd(c))
  345.                 serror("Mark what?|%s requires following letter", Command);
  346.             newline();
  347.             if (!islower(c))
  348.                 error("Bad mark|Mark must specify a letter");
  349.             setdot();
  350.             nonzero();
  351.             names[c - 'a'] = *addr2 &~ 01;
  352.             anymarks = 1;
  353.             continue;
  354.  
  355. /* list */
  356.         case 'l':
  357.             tail("list");
  358.             setCNL();
  359.             ignorf(setlist(1));
  360.             pflag = 0;
  361.             goto print;
  362.  
  363.         case 'm':
  364.             if (peekchar() == 'a') {
  365.                 ignchar();
  366.                 if (peekchar() == 'p') {
  367. /* map */
  368.                     tail2of("map");
  369.                     setnoaddr();
  370.                     mapcmd(0, 0);
  371.                     continue;
  372.                 }
  373. /* mark */
  374.                 tail2of("mark");
  375.                 goto casek;
  376.             }
  377. /* move */
  378.             tail("move");
  379.             vmacchng(0);
  380.             move();
  381.             continue;
  382.  
  383.         case 'n':
  384.             if (peekchar() == 'u') {
  385.                 tail("number");
  386.                 goto numberit;
  387.             }
  388. /* next */
  389.             tail("next");
  390.             setnoaddr();
  391.             ckaw();
  392.             ignore(quickly());
  393.             if (getargs())
  394.                 makargs();
  395.             next();
  396.             c = 'e';
  397.             filename(c);
  398.             goto doecmd;
  399.  
  400. /* open */
  401.         case 'o':
  402.             tail("open");
  403.             oop();
  404.             pflag = 0;
  405.             nochng();
  406.             continue;
  407.  
  408.         case 'p':
  409.         case 'P':
  410.             switch (peekchar()) {
  411.  
  412. /* put */
  413.             case 'u':
  414.                 tail("put");
  415.                 setdot();
  416.                 c = cmdreg();
  417.                 eol();
  418.                 vmacchng(0);
  419.                 if (c)
  420.                     putreg(c);
  421.                 else
  422.                     put();
  423.                 continue;
  424.  
  425.             case 'r':
  426.                 ignchar();
  427.                 if (peekchar() == 'e') {
  428. /* preserve */
  429.                     tail2of("preserve");
  430.                     eol();
  431.                     if (preserve() == 0)
  432.                         error("Preserve failed!");
  433.                     else
  434.                         error("File preserved.");
  435.                 }
  436.                 tail2of("print");
  437.                 break;
  438.  
  439.             default:
  440.                 tail("print");
  441.                 break;
  442.             }
  443. /* print */
  444.             setCNL();
  445.             pflag = 0;
  446. print:
  447.             nonzero();
  448.             if (CL && span() > LINES) {
  449.                 flush1();
  450.                 vclear();
  451.             }
  452.             plines(addr1, addr2, 1);
  453.             continue;
  454.  
  455. /* quit */
  456.         case 'q':
  457.             tail("quit");
  458.             setnoaddr();
  459.             c = quickly();
  460.             eol();
  461.             if (!c)
  462. quit:
  463.                 nomore();
  464.             if (inopen) {
  465.                 vgoto(WECHO, 0);
  466.                 if (!ateopr())
  467.                     vnfl();
  468.                 else {
  469.                     tostop();
  470.                 }
  471.                 flush();
  472.                 ignore(setty(normf));
  473.             }
  474.             cleanup(1);
  475.             ex_exit(0);
  476.  
  477.         case 'r':
  478.             if (peekchar() == 'e') {
  479.                 ignchar();
  480.                 switch (peekchar()) {
  481.  
  482. /* rewind */
  483.                 case 'w':
  484.                     tail2of("rewind");
  485.                     setnoaddr();
  486.                     if (!exclam()) {
  487.                         ckaw();
  488.                         if (chng && dol > zero)
  489.                             error("No write@since last chage (:rewind! overrides)");
  490.                     }
  491.                     eol();
  492.                     erewind();
  493.                     next();
  494.                     c = 'e';
  495.                     ungetchar(lastchar());
  496.                     filename(c);
  497.                     goto doecmd;
  498.  
  499. /* recover */
  500.                 case 'c':
  501.                     tail2of("recover");
  502.                     setnoaddr();
  503.                     c = 'e';
  504.                     if (!exclam() && chng)
  505.                         c = 'E';
  506.                     filename(c);
  507.                     if (c == 'E') {
  508.                         ungetchar(lastchar());
  509.                         ignore(quickly());
  510.                     }
  511.                     init();
  512.                     addr2 = zero;
  513.                     laste++;
  514.                     ex_sync();
  515.                     recover();
  516.                     rop2();
  517.                     revocer();
  518.                     if (status == 0)
  519.                         rop3(c);
  520.                     if (dol != zero)
  521.                         change();
  522. #ifdef VMUNIX
  523.                     tlaste();
  524. #endif
  525.                     laste = 0;
  526.                     nochng();
  527.                     continue;
  528.                 }
  529.                 tail2of("read");
  530.             } else
  531.                 tail("read");
  532. /* read */
  533.             if (savedfile[0] == 0 && dol == zero)
  534.                 c = 'e';
  535.             pastwh();
  536.             vmacchng(0);
  537.             if (peekchar() == '!') {
  538.                 setdot();
  539.                 ignchar();
  540.                 unix0(0);
  541.                 filter(0);
  542.                 continue;
  543.             }
  544.             filename(c);
  545.             rop(c);
  546.             nochng();
  547.             if (inopen && endline && addr1 > zero && addr1 < dol)
  548.                 dot = addr1 + 1;
  549.             continue;
  550.  
  551.         case 's':
  552.             switch (peekchar()) {
  553.             /*
  554.              * Caution: 2nd char cannot be c, g, or r
  555.              * because these have meaning to substitute.
  556.              */
  557.  
  558. /* set */
  559.             case 'e':
  560.                 tail("set");
  561.                 setnoaddr();
  562.                 set();
  563.                 continue;
  564.  
  565. /* shell */
  566.             case 'h':
  567.                 tail("shell");
  568.                 setNAEOL();
  569.                 vnfl();
  570.                 putpad(TE);
  571.                 flush();
  572.                 unixwt(1, unixex("-i", (char *) 0, 0, 0));
  573.                 vcontin(0);
  574.                 continue;
  575.  
  576. /* source */
  577.             case 'o':
  578. #ifdef notdef
  579.                 if (inopen)
  580.                     goto notinvis;
  581. #endif
  582.                 tail("source");
  583.                 setnoaddr();
  584.                 getone();
  585.                 eol();
  586.                 source(file, 0);
  587.                 continue;
  588. #ifdef SIGTSTP
  589. /* stop, suspend */
  590.             case 't':
  591.                 tail("stop");
  592.                 goto suspend;
  593.             case 'u':
  594.                 tail("suspend");
  595. suspend:
  596.                 if (!ldisc)
  597.                     error("Old tty driver|Not using new tty driver/shell");
  598.                 c = exclam();
  599.                 eol();
  600.                 if (!c)
  601.                     ckaw();
  602.                 onsusp();
  603.                 continue;
  604. #endif
  605.  
  606.             }
  607.             /* fall into ... */
  608.  
  609. /* & */
  610. /* ~ */
  611. /* substitute */
  612.         case '&':
  613.         case '~':
  614.             Command = "substitute";
  615.             if (c == 's')
  616.                 tail(Command);
  617.             vmacchng(0);
  618.             if (!substitute(c))
  619.                 pflag = 0;
  620.             continue;
  621.  
  622. /* t */
  623.         case 't':
  624.             if (peekchar() == 'a') {
  625.                 tail("tag");
  626.                 tagfind(exclam());
  627.                 if (!inopen)
  628.                     lchng = chng - 1;
  629.                 else
  630.                     nochng();
  631.                 continue;
  632.             }
  633.             tail("t");
  634.             vmacchng(0);
  635.             move();
  636.             continue;
  637.  
  638.         case 'u':
  639.             if (peekchar() == 'n') {
  640.                 ignchar();
  641.                 switch(peekchar()) {
  642. /* unmap */
  643.                 case 'm':
  644.                     tail2of("unmap");
  645.                     setnoaddr();
  646.                     mapcmd(1, 0);
  647.                     continue;
  648. /* unabbreviate */
  649.                 case 'a':
  650.                     tail2of("unabbreviate");
  651.                     setnoaddr();
  652.                     mapcmd(1, 1);
  653.                     anyabbrs = 1;
  654.                     continue;
  655.                 }
  656. /* undo */
  657.                 tail2of("undo");
  658.             } else
  659.                 tail("undo");
  660.             setnoaddr();
  661.             markDOT();
  662.             c = exclam();
  663.             newline();
  664.             undo(c);
  665.             continue;
  666.  
  667.         case 'v':
  668.             switch (peekchar()) {
  669.  
  670.             case 'e':
  671. /* version */
  672.                 tail("version");
  673.                 setNAEOL();
  674.                 ex_printf("@(#) Version 3.7, 6/7/85."+5);
  675.                 noonl();
  676.                 continue;
  677.  
  678. /* visual */
  679.             case 'i':
  680.                 tail("visual");
  681.                 if (inopen) {
  682.                     c = 'e';
  683.                     goto editcmd;
  684.                 }
  685.                 vop();
  686.                 pflag = 0;
  687.                 nochng();
  688.                 continue;
  689.             }
  690. /* v */
  691.             tail("v");
  692.             global(0);
  693.             nochng();
  694.             continue;
  695.  
  696. /* write */
  697.         case 'w':
  698.             c = peekchar();
  699.             tail(c == 'q' ? "wq" : "write");
  700. wq:
  701.             if (skipwh() && peekchar() == '!') {
  702.                 pofix();
  703.                 ignchar();
  704.                 setall();
  705.                 unix0(0);
  706.                 filter(1);
  707.             } else {
  708.                 setall();
  709.                 wop(1);
  710.                 nochng();
  711.             }
  712.             if (c == 'q')
  713.                 goto quit;
  714.             continue;
  715.  
  716. /* xit */
  717.         case 'x':
  718.             tail("xit");
  719.             if (!chng)
  720.                 goto quit;
  721.             c = 'q';
  722.             goto wq;
  723.  
  724. /* yank */
  725.         case 'y':
  726.             tail("yank");
  727.             c = cmdreg();
  728.             setcount();
  729.             eol();
  730.             vmacchng(0);
  731.             if (c)
  732.                 YANKreg(c);
  733.             else
  734.                 yank();
  735.             continue;
  736.  
  737. /* z */
  738.         case 'z':
  739.             zop(0);
  740.             pflag = 0;
  741.             continue;
  742.  
  743. /* * */
  744. /* @ */
  745.         case '*':
  746.         case '@':
  747.             c = ex_getchar();
  748.             if (c=='\n' || c=='\r')
  749.                 ungetchar(c);
  750.             if (any(c, "@*\n\r"))
  751.                 c = lastmac;
  752.             if (isupper(c))
  753.                 c = tolower(c);
  754.             if (!islower(c))
  755.                 error("Bad register");
  756.             newline();
  757.             setdot();
  758.             cmdmac(c);
  759.             continue;
  760.  
  761. /* | */
  762.         case '|':
  763.             endline = 0;
  764.             goto caseline;
  765.  
  766. /* \n */
  767.         case '\n':
  768.             endline = 1;
  769. caseline:
  770.             notempty();
  771.             if (addr2 == 0) {
  772.                 if (UP != NOSTR && c == '\n' && !inglobal)
  773.                     c = CTRL(k);
  774.                 if (inglobal)
  775.                     addr1 = addr2 = dot;
  776.                 else {
  777.                     if (dot == dol)
  778.                         error("At EOF|At end-of-file");
  779.                     addr1 = addr2 = dot + 1;
  780.                 }
  781.             }
  782.             setdot();
  783.             nonzero();
  784.             if (seensemi)
  785.                 addr1 = addr2;
  786.             getline(*addr1);
  787.             if (c == CTRL(k)) {
  788.                 flush1();
  789.                 destline--;
  790.                 if (hadpr)
  791.                     shudclob = 1;
  792.             }
  793.             plines(addr1, addr2, 1);
  794.             continue;
  795.  
  796. /* " */
  797.         case '"':
  798.             comment();
  799.             continue;
  800.  
  801. /* # */
  802.         case '#':
  803. numberit:
  804.             setCNL();
  805.             ignorf(setnumb(1));
  806.             pflag = 0;
  807.             goto print;
  808.  
  809. /* = */
  810.         case '=':
  811.             newline();
  812.             setall();
  813.             if (inglobal == 2)
  814.                 pofix();
  815.             ex_printf("%d", lineno(addr2));
  816.             noonl();
  817.             continue;
  818.  
  819. /* ! */
  820.         case '!':
  821.             if (addr2 != 0) {
  822.                 vmacchng(0);
  823.                 unix0(0);
  824.                 setdot();
  825.                 filter(2);
  826.             } else {
  827.                 unix0(1);
  828.                 pofix();
  829.                 putpad(TE);
  830.                 flush();
  831.                 unixwt(1, unixex("-c", uxb, 0, 0));
  832.                 vclrech(1);    /* vcontin(0); */
  833.                 nochng();
  834.             }
  835.             continue;
  836.  
  837. /* < */
  838. /* > */
  839.         case '<':
  840.         case '>':
  841.             for (cnt = 1; peekchar() == c; cnt++)
  842.                 ignchar();
  843.             setCNL();
  844.             vmacchng(0);
  845.             shift(c, cnt);
  846.             continue;
  847.  
  848. /* ^D */
  849. /* EOF */
  850.         case CTRL(d):
  851.         case EOF:
  852.             if (exitoneof) {
  853.                 if (addr2 != 0)
  854.                     dot = addr2;
  855.                 return;
  856.             }
  857.             if (!isatty(0)) {
  858.                 if (intty)
  859.                     /*
  860.                      * Chtty sys call at UCB may cause a
  861.                      * input which was a tty to suddenly be
  862.                      * turned into /dev/null.
  863.                      */
  864.                     onhup();
  865.                 return;
  866.             }
  867.             if (addr2 != 0) {
  868.                 setlastchar('\n');
  869.                 putnl();
  870.             }
  871.             if (dol == zero) {
  872.                 if (addr2 == 0)
  873.                     putnl();
  874.                 notempty();
  875.             }
  876.             ungetchar(EOF);
  877.             zop(hadpr);
  878.             continue;
  879.  
  880.         default:
  881.             if (!isalpha(c))
  882.                 break;
  883.             ungetchar(c);
  884.             tailprim("", 0, 0);
  885.         }
  886.         error("What?|Unknown command character '%c'", c);
  887.     }
  888. }
  889.